﻿
//常量表达式计算器
namespace n_ConstExpression
{
using System;
using System.Text;
using n_ConstString;
using n_ET;

public static class ConstExpression
{
	//计算表达式
	public static StringBuilder Expression( string Source )
	{
		//常量列表 格式: 常量符号,常量值 常量符号,常量值 ....
		string ConstSet = null;
		
		StringBuilder Result = new StringBuilder( "" );
		string[] Cut = Source.TrimEnd( '\n' ).Split( '\n' );
		
		//遍历目标指令序列
		for( int i = 0; i < Cut.Length; ++i ) {
			
			if( Cut[ i ].StartsWith( "#endif" ) ) {
				continue;
			}
			//如果常量集合不为空, 替换常量表达式
			if( ConstSet != null ) {
				string[] ConstCut = ConstSet.TrimEnd( ' ' ).Split( ' ' );
				for( int k = 0; k < ConstCut.Length; ++k ) {
					string[] SignAndValue = ConstCut[ k ].Split( ',' );
					Cut[ i ] = Cut[ i ].Replace( SignAndValue[ 0 ], SignAndValue[ 1 ] );
				}
			}
			//如果是表达式, 计算值并添加到常量集合
			if( Cut[ i ].StartsWith( "$" ) ) {
				ConstSet += GetValue( Cut[ i ] ) + " ";
				continue;
			}
			//如果是条件选择指令, 根据真值确定是否跳过相关指令序列
			if( Cut[ i ].StartsWith( "#if " ) ) {
				string BoolValue = Cut[ i ].Split( ' ' )[ 1 ];
				if( int.Parse( BoolValue ) != 0 ) {
					continue;
				}
				do {
				++i;
				} while( !Cut[ i ].StartsWith( "#endif" ) );
				continue;
			}
			//到这里是普通指令
			Result.Append( Cut[ i ] + "\n" );
		}
		return Result;
	}
	
	//计算一个表达式的值, 返回结果形式: 常量符号,常量值
	static string GetValue( string Exp )
	{
		string[] Cut = Exp.Split( ' ' );
		
		//判断是否为赋值运算
		if( Cut.Length == 3 ) {
			return 赋值运算( Cut );
		}
		//判断是否为单目运算
		if( Cut.Length == 4 ) {
			return 单目运算( Cut );
		}
		//判断是否双目运算
		if( Cut.Length == 5 ) {
			return 双目运算( Cut );
		}
		ET.ShowError( "未知的常量表达式类型: " + Exp );
		return null;
	}
	
	//计算赋值表达式, 返回结果形式: 常量符号,常量值
	static string 赋值运算( string[] Cut )
	{
		string Type = null;
		int Value = int.Parse( ConstString.GetValue( ref Type, Cut[ 2 ], 0 ) );
		return Cut[ 0 ] + "," + Value;
	}
	
	//计算单目表达式, 返回结果形式: 常量符号,常量值
	static string 单目运算( string[] Cut )
	{
		string Type = null;
		int Value = int.Parse( ConstString.GetValue( ref Type, Cut[ 3 ], 0 ) );
		if( Cut[ 2 ] == "-" ) {
			return Cut[ 0 ] + "," + -Value;
		}
		if( Cut[ 2 ] == "!" ) {
			if( Value == 0 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		ET.ShowError( "未定义的单目运算: " + Cut[ 2 ] );
		return null;
	}
	
	//计算双目表达式, 返回结果形式: 常量符号,常量值
	static string 双目运算( string[] Cut )
	{
		string Type = null;
		if( Cut[ 3 ] == "string_equal" ) {
			if( Cut[ 2 ] == Cut[ 4 ] ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		ulong Value1 = ulong.Parse( ConstString.GetValue( ref Type, Cut[ 2 ], 0 ) );
		ulong Value2 = ulong.Parse( ConstString.GetValue( ref Type, Cut[ 4 ], 0 ) );
		if( Cut[ 3 ] == "+" ) {
			return Cut[ 0 ] + "," + ( Value1 + Value2 );
		}
		if( Cut[ 3 ] == "-" ) {
			return Cut[ 0 ] + "," + ( Value1 - Value2 );
		}
		if( Cut[ 3 ] == "*" ) {
			return Cut[ 0 ] + "," + ( Value1 * Value2 );
		}
		if( Cut[ 3 ] == "/" ) {
			return Cut[ 0 ] + "," + ( Value1 / Value2 );
		}
		if( Cut[ 3 ] == "%" ) {
			return Cut[ 0 ] + "," + ( Value1 % Value2 );
		}
		if( Cut[ 3 ] == "`" ) {
			return Cut[ 0 ] + "," + ( (ulong)Math.Pow( Value1, (int)( Value2 % 256 ) ) );
		}
		if( Cut[ 3 ] == "<<" ) {
			return Cut[ 0 ] + "," + ( Value1 << (int)( Value2 % 256 ) );
		}
		if( Cut[ 3 ] == ">>" ) {
			return Cut[ 0 ] + "," + ( Value1 >> (int)( Value2 % 256 ) );
		}
		if( Cut[ 3 ] == "&&" ) {
			if( Value1 != 0 && Value2 != 0 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		if( Cut[ 3 ] == "||" ) {
			if( Value1 != 0 || Value2 != 0 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		if( Cut[ 3 ] == ">" ) {
			if( Value1 > Value2 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		if( Cut[ 3 ] == "<" ) {
			if( Value1 < Value2 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		if( Cut[ 3 ] == ">=" ) {
			if( Value1 >= Value2 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		if( Cut[ 3 ] == "<=" ) {
			if( Value1 <= Value2 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		if( Cut[ 3 ] == "==" ) {
			if( Value1 == Value2 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		if( Cut[ 3 ] == "!=" ) {
			if( Value1 != Value2 ) {
				return Cut[ 0 ] + ",1";
			}
			else {
				return Cut[ 0 ] + ",0";
			}
		}
		ET.ShowError( "未定义的双目运算: " + Cut[ 3 ] );
		return null;
	}
}
}



